﻿using BZ.Logger;
using HalconDotNet;
using NDK.Module.BLL;
using NDK.Module.Model;
using NDK.Motion.BLL;
using NDK.Motion.Monitor;
using NDK.Utils;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using static NDK.Module.Model.Common;

namespace NDK.Module.StationLogic
{
    public class LoadingProduct : StationLogicBase
    {
        #region 通用
        public override event PropertyChangedEventHandler PropertyChanged;
        private StationStep _curStep = StationStep.WaitMacInit;
        public static LoadingProduct Instance = new LoadingProduct();
        private LoadingProduct() : base()
        {
            this.Name = "上料产品定位";
        }
        //步骤字段、属性
        private StationStep _step = StationStep.WaitMacInit;
        [Monitor(Description = "当前步骤")]
        public StationStep Step
        {
            get
            {
                return _step;
            }
            set
            {
                if (_curStep != value)
                {
                    _step = value;
                    _curStep = value;
                    FileUtils.WriteLogToTxt($"{Step.ToString()}  CT:{Math.Round((double)swStepTime.ElapsedMilliseconds / 1000, 3)}s", logFold, logBaseInfo, isWriteLog);
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(value.ToString()));
                    swStepTime.Restart();
                }
            }
        }
        #endregion


        #region 变量
        public event delegateUpdatePLC delegateUpdatePLCEvent;
        string str = string.Empty;
        HImage hImage = null;
        int CountCalib;
        #endregion

        /// <summary>
        /// 工站初始化
        /// </summary>
        public override void Init()
        {
            base.Init();
            Step = StationStep.WaitMacInit;
            logBaseInfo = "上料产品定位";
            Machine.OmronPLC_Up.WriteBool(stModule_0_PC_PLC_B_0, false);
            str = string.Empty;
            hImage = new HImage();
        }

        public override void ActionProcess()
        {
            try
            {
                switch (this.Step)
                {
                    case StationStep.WaitMacInit:
                        Step = StationStep.Start;
                        break;
                    case StationStep.Start:
                        Step = StationStep.等待光源打开;
                        break;
                    case StationStep.等待光源打开:
                        Step = StationStep.等待定位请求拍照信号;
                        break;
                    case StationStep.等待定位请求拍照信号:
                        if (Machine.OmronPLC_Up.ReadBool(stModule_0_PLC_PC_B_0))
                        {
                            Machine.DicLight["定位拍照"].Open();
                            Step = StationStep.相机拍照;
                        }
                        break;
                    case StationStep.相机拍照:
                        hImage = PublicMethod.GradImage("定位相机", Machine.DirExp["定位相机"]);
                        CountCalib = Machine.OmronPLC_Up.ReadInt16(stCom_0_W_0);
                        if (CountCalib == 0)
                            Step = StationStep.视觉计算处理;
                        else
                            Step = StationStep.自动标定;
                        break;
                    case StationStep.视觉计算处理:
                        List<DataItem> listDataItem = new List<DataItem>();
                        List<DataItem> listDataItem1 = new List<DataItem>();
                        List<DataItem> listDataItem2 = new List<DataItem>();
                        if (CurProType.Contains("Block"))
                        {
                            EventVisoion.PosionRefresh(new PosionImageRefreshEventArgs()
                            {
                                SN = DateTime.Now.ToString("yyyyMMddHHmmssff"),
                                FileName = "Position_block",
                                outDataName = "PositionX",
                                outDataName1 = "PositionY",
                                outDataName2 = "PositionA",
                                Imagesname = new List<string>() { "定位CCD1" },
                                Images = new List<HImage>() { hImage }
                            }, ref listDataItem, ref listDataItem1, ref listDataItem2);
                        }
                        else
                        {
                            EventVisoion.PosionRefresh(new PosionImageRefreshEventArgs()
                            {
                                SN = DateTime.Now.ToString("yyyyMMddHHmmssff"),
                                FileName = "Position1",
                                outDataName = "PositionX",
                                outDataName1 = "PositionY",
                                outDataName2 = "PositionA",
                                Imagesname = new List<string>() { "定位CCD1" },
                                Images = new List<HImage>() { hImage }
                            }, ref listDataItem, ref listDataItem1, ref listDataItem2);
                        }

                        double X_A = 9999;
                        double Y_A = 9999;
                        double R_A = 9999;
                        double X_B = 9999;
                        double Y_B = 9999;
                        double R_B = 9999;
                        if (listDataItem != null)
                        {
                            X_A = Math.Round((listDataItem[0].Value + 偏移量X_A) * 10000);
                            Y_A = Math.Round((listDataItem[1].Value + 偏移量Y_A) * 10000);
                            R_A = Math.Round((listDataItem[2].Value + 偏移量R_A) * 10000);
                            X_B = Math.Round((listDataItem[3].Value + 偏移量X_B) * 10000);
                            Y_B = Math.Round((listDataItem[4].Value + 偏移量Y_B) * 10000);
                            R_B = Math.Round((listDataItem[5].Value + 偏移量R_B) * 10000);

                        }

                        List<float> listfloat = new List<float>();
                        listfloat.Add(float.Parse(X_A.ToString()));
                        listfloat.Add(float.Parse(Y_A.ToString()));
                        listfloat.Add(float.Parse(R_A.ToString()));
                        listfloat.Add(float.Parse(X_B.ToString()));
                        listfloat.Add(float.Parse(Y_B.ToString()));
                        listfloat.Add(float.Parse(R_B.ToString()));

                        string strlog = $"A爪 X:{X_A} Y:{Y_A} R:{R_A} B爪 X:{X_B} Y:{Y_B} R:{R_B}";
                        Machine.OmronPLC_Up.WriteFloats(wLdBeltPdt_OFFSET, listfloat.ToArray());

                        AppendUiLog.Log($"上料Tray盘定位：{strlog} !", LogType.Info);
                        Step = StationStep.发送拍照完成信号;
                        break;
                    case StationStep.自动标定:
                        float FX = Machine.OmronPLC_Up.ReadFloat(stCom_0_PLC_PC_CCD_X);
                        float FY = Machine.OmronPLC_Up.ReadFloat(stCom_0_PLC_PC_CCD_Y);
                        float FR = Machine.OmronPLC_Up.ReadFloat(stCom_0_PLC_PC_CCD_R);
                        FileUtils.WriteLogToTxt($"当前第{CountCalib}次拍照 X:{FX} Y:{FY} R:{FR}", logFold, "自动9点标定机械手点位");
                        string dirPath = "E:\\定位图片\\标定";
                        if (!Directory.Exists(dirPath))
                            Directory.CreateDirectory(dirPath);
                        HOperatorSet.WriteImage(hImage, "bmp", 0, $"{dirPath}\\{CountCalib}.bmp");
                        Step = StationStep.发送拍照完成信号;
                        break;
                    case StationStep.发送拍照完成信号:
                        Machine.OmronPLC_Up.WriteBool(stModule_0_PC_PLC_B_0, true);
                        Step = StationStep.End;
                        break;
                    case StationStep.End:
                        if (!Machine.OmronPLC_Up.ReadBool(stModule_0_PLC_PC_B_0))
                        {
                            Machine.DicLight["定位拍照"].Close();
                            Machine.OmronPLC_Up.WriteBool(stModule_0_PC_PLC_B_0, false);

                            if (SaveImage(hImage, "定位图片"))
                            {
                                hImage = null;
                            }
                        }
                        Step = StationStep.WaitMacInit;
                        break;
                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
                UILog_Error($"[ {logBaseInfo} ActionProcess Thread ERROR] {ex.Message}");
                if (AlarmPause(logBaseInfo, $"当前状态:{Step} 报警异常:{ex.Message}", "点击确定，再试一次；点击取消，继续运行", "再试一次", "继续运行") == DialogResult.OK)
                {

                }
            }
        }
        public bool SaveImage(HObject image, string path)
        {
            bool ret = true;
            if (保存定位图片 && image != null)
            {
                string dirPath = $"E:\\{path}\\{DateTime.Now.ToString("yyyy-MM-dd")}";
                bool IsFullSpace = false;
                List<string> strings = new List<string>() { "E", "F", "G" };
                foreach (var item in strings)
                {
                    if (!IsFullSpace)
                    {
                        if (PublicMethod.GetHardDiskFreeSpace(item) > 10)
                        {
                            IsFullSpace = true;
                            dirPath = dirPath.Remove(0, 1);
                            dirPath = item + dirPath;
                        }
                    }
                }
                if (!IsFullSpace)
                    MessageBox.Show("磁盘即将占满，请注意观察");
                try
                {
                    if (!FileUtils.IsExistDirectory(dirPath))
                    {
                        FileUtils.CreateDirectory(dirPath);
                    }

                    HOperatorSet.WriteImage(image, "jpg", 0, dirPath + "\\" + DateTime.Now.ToString("HHmmss") + ".jpg");
                }
                catch (Exception exc)
                {
                    ret = false;
                }
            }
            return ret;
        }
        public override void EmptyActionProcess()
        {
            ActionProcess();
        }

        public override void GRRActionProcess()
        {
            ActionProcess();
        }
        public enum StationStep
        {
            /// <summary>
            /// 等待机台初始化
            /// </summary>
            [Description("等待机台初始化")]
            WaitMacInit,
            [Description("开始")]
            Start,
            等待光源打开,
            等待定位请求拍照信号,
            相机拍照,
            视觉计算处理,
            自动标定,
            发送拍照完成信号,
            [Description("工站完成")]
            End,
        }
    }
}
